'''
'''

import PyQt4
from PyQt4 import Qt
from PyQt4.QtGui import QApplication, QTableView, QAbstractItemView, QDialog, QMenu
from PyQt4.QtCore import (QString, QModelIndex, QVariant, SIGNAL, pyqtSignature, 
                          QModelIndex)

from SimpleCells.Components.Table.SCTableViewTools import *
from SimpleCells.Components.Table.SCTableDelegate import SCTableDelegate
from SimpleCells.Gui.SCDateSchedDialog import SCDateSchedDialog

class SCTableView(QTableView):
    '''The base table view for SimpleCells.
    '''
    
    def __init__(self, parent):
        QTableView.__init__(self,parent)
        self.setItemDelegate(SCTableDelegate(self))

    def insert(self,content,firstIndex):
        '''Inserts matrix elements in the table.
        '''
        model = self.model()
        SCTableWriteTools.checkSpace(content,model,firstIndex)
        for i, row in enumerate(content):
            for j, elem in enumerate(row):
                if not elem.isEmpty():
                    index = model.index(firstIndex.row()+i,firstIndex.column()+j)
                    model.recordData(index,QVariant(elem))
        lastIndex = model.index(firstIndex.row()+i,firstIndex.column()+j)
        model.emit(SIGNAL("dataChanged(QModelIndex,QModelIndex)"),firstIndex,lastIndex)

    def convertSelection(self,toWhat):
        indexes = self.selectedIndexes()
        for i in indexes:
            self.model().convertCell(i,toWhat)

    @pyqtSignature("")
    def lockSelection(self):
        indexes = self.selectedIndexes()
        for i in indexes:
            self.model().lockData(i)

    @pyqtSignature("")
    def unlockSelection(self):
        indexes = self.selectedIndexes()
        for i in indexes:
            self.model().unlockData(i)
    
    @pyqtSignature("")
    def emptySelection(self):
        '''Empties the cell selection.
        '''
        if self.editTriggers() != QAbstractItemView.NoEditTriggers:
            indexes = self.selectedIndexes()
            model = self.model()
            for i in indexes:
                model.recordData(i,QVariant(QString("")))
            model.emit(SIGNAL("dataChanged(QModelIndex,QModelIndex)"),indexes[0],indexes[-1])

    @pyqtSignature("")
    def clearAll(self):
        self.model().clearAll()

    @pyqtSignature("int,int")
    def resetAll(self,rows,cols):
        self.model().resetAll(rows,cols)

    @pyqtSignature("int")
    def addRows(self,rows):
        self.model().addRows(rows)
    
    @pyqtSignature("int")
    def addColumns(self,cols):
        self.model().addColumns(cols)

    def deleteSelectedRows(self):
        indexes = self.selectedIndexes()
        if len(indexes) <= 0: return
        rowMin, rowMax, _, _ = SCTablePositionTools.getRect(indexes)
        if rowMax-rowMin == self.model().rowCount(): return
        self.model().removeRows(rowMin,rowMax-rowMin)
    
    def deleteSelectedCols(self):
        indexes = self.selectedIndexes()
        if len(indexes) <= 0: return
        _,_,colMin,colMax = SCTablePositionTools.getRect(indexes)
        if colMax-colMin == self.model().columnCount(): return
        self.model().removeColumns(colMin,colMax-colMin)
    
    def paste(self,transpose=False):
        '''Pastes a list of data contained in the clipboard
        in text format.
        '''
        clipboard = QApplication.clipboard()
        if clipboard.mimeData().hasText():
            content = SCTableView.decodeClipboard(clipboard.text())
            if transpose:
                content = SCTableView.transposeList(content)
            self.insert(content,self.selectedIndexes()[0])
        
    def copy(self,evaluate=False):
        '''Copies a list of data from the table and put it
        on the clipboard in text format.
        '''
        var = SCTableReadTools.selectionToText(self,evaluate)
        clipboard = QApplication.clipboard()
        clipboard.setText(var)

    def cut(self,evaluate=False):
        '''Cuts a list of data from the table and put it
        on the clipboard in text format.
        '''
        self.copy(evaluate)
        self.emptySelection()

    def generateValues(self,algo='firstTwo'):
        '''Automatically generate values based on the difference\
            between the first two values of a series.'''
        indexes = self.selectedIndexes()
        if algo == 'firstTwo':
            SCTableGenerationTool.generateValues(self.model(), indexes)
        elif algo == 'firstLast':
            SCTableGenerationTool.fillInValues(self.model(), indexes)
        elif algo == 'repeatFirst':
            SCTableGenerationTool.repeatValue(self.model(), indexes)
    
    def generateDates(self):
        indexes = self.selectedIndexes()
#        assert SCTablePositionTools.getDimension(indexes) == 1, \
#            'Wrong selection dimension'
        nRows, nCols = SCTablePositionTools.getShape(indexes)
        dateSched = SCDateSchedDialog(max(nRows,nCols),self)
        map(dateSched.freqBox.addItem,SCDateSchedDialog.FREQ.keys())
        if dateSched.exec_():
            dates = dateSched.dateList
            if not dateSched.fillDirection:
                dates = iter(dates)
                for idx in indexes:
                    self.model().setData(idx,dates.next().date())
            else:
                firstIdx = indexes[0]
                nDates = len(dates)
                if dateSched.fillDirection == 'horizontally':
                    for i in range(nDates):
                        idx = self.model().index(firstIdx.row(),firstIdx.column()+i)
                        self.model().setData(idx,dates[i].date())
                else:
                    for i in range(nDates):
                        idx = self.model().index(firstIdx.row()+i,firstIdx.column())
                        self.model().setData(idx,dates[i].date())

    def insertToday(self):
        index = self.selectedIndexes()[0]
        SCTableGenerationTool.insertToday(self.model(), index)

    @staticmethod
    def decodeClipboard(text):
        out = []
        textRows = map(None,text.split(eolChar))
        for row in textRows:
            line = QString(row).split("\t")
            out.append(map(None,line))
        return out
    
    @staticmethod
    def transposeList(lists):
        out = []
        if hasattr(lists[0],'__iter__'):
            if not lists: return out
            out = map(lambda *row: list(row), *lists)
        else:
            out = map(lambda col: list(col), lists)
        for i, row in enumerate(out):
            if not hasattr(out[i],'__iter__'): continue 
            out[i] = filter(lambda x: x is not None, row)
        return out

def test():
    if QApplication.startingUp():
        QApplication([])
    dialog = QDialog(None)
    grid_layout = QGridLayout()
    widget = SCTableView(None)
    model = SCTableModel(10,10)
    widget.setModel(model)
    grid_layout.addWidget(widget)
    dialog.setLayout(grid_layout)
    dialog.exec_()
    
if __name__ == '__main__':
    from PyQt4.QtGui import QApplication, QDialog, QGridLayout
    from SimpleCells.Components.Table.SCTableModel import SCTableModel 
    from SimpleCells.Components.Table.SCTableData import SCTableData
    test()